﻿using System;
using System.Diagnostics;
using System.Security.Principal;
using System.Runtime.InteropServices;

    public class Logger
    {
        public static void Error(String Messege)
        {
            Logging.WriteEventLogTextEntryApi(Messege, Logging.EVENTLOG_ERROR_TYPE, 1, null);
        }

        public static void Info(String Messege)
        {
            Logging.WriteEventLogTextEntryApi(Messege, Logging.EVENTLOG_INFORMATION_TYPE, 1, null);
        }

        public static void Warning(String Messege)
        {
            Logging.WriteEventLogTextEntryApi(Messege, Logging.EVENTLOG_INFORMATION_TYPE, 1, null);
        }

        public static void SuccessAudit(String Messege)
        {
            Logging.WriteEventLogTextEntryApi(Messege, Logging.EVENTLOG_AUDIT_SUCCESS, 1, null);
        }

        public static void FailureAudit(String Messege)
        {
            Logging.WriteEventLogTextEntryApi(Messege, Logging.EVENTLOG_AUDIT_FAILURE, 1, null);
        }

    }

    public class Logging
    {
        [DllImport("advapi32.dll")]
        private static extern IntPtr RegisterEventSource(string lpUNCServerName, string lpSourceName);
        [DllImport("advapi32.dll")]
        private static extern bool DeregisterEventSource(IntPtr hEventLog);
        [DllImport("advapi32.dll", EntryPoint = "ReportEventW", CharSet = CharSet.Unicode)]
        private static extern bool ReportEvent(
                    IntPtr hEventLog,
                    ushort wType,
                    ushort wCategory,
                    int dwEventID,
                    IntPtr lpUserSid,
                    ushort wNumStrings,
                    uint dwDataSize,
                    string[] lpStrings,
                    byte[] lpRawData
                    );
        public const ushort EVENTLOG_INFORMATION_TYPE = 0x0004;
        public const ushort EVENTLOG_WARNING_TYPE = 0x0002;
        public const ushort EVENTLOG_ERROR_TYPE = 0x0001;
        public const ushort EVENTLOG_SUCCESS = 0x0000;
        public const ushort EVENTLOG_AUDIT_FAILURE = 0x0010;
        public const ushort EVENTLOG_AUDIT_SUCCESS = 0x0008;

        public static void WriteEventLogTextEntryApi(string text, ushort logType, int logEventId, byte[] rawData)
        {
            //Temporary registry of eventsource

            //IntPtr hEventLog = RegisterEventSource(null, "EventSourceName");
            IntPtr hEventLog = RegisterEventSource(null, Globals.assemblyTitle);

            uint dataSize = (uint)(rawData != null ? rawData.Length : 0);

            // find form
            StackTrace stackTrace = new StackTrace();           // get call stack
            StackFrame[] stackFrames = stackTrace.GetFrames();  // get method calls (frames)

            string form = ""; ;
            // write call stack method names
            foreach (StackFrame stackFrame in stackFrames)
            {
                //   Console.WriteLine(stackFrame.GetMethod().Name);   // write method name
                form = stackFrame.GetMethod().ReflectedType.Name;
                if (form.Contains("frm"))
                    break;
                else
                    form = "";
            }
            //

            if (form.Trim().Length > 0)
                text = form + ":\n" + text;


            //Write event to eventlog
            ReportEvent(hEventLog, logType, 0, logEventId, IntPtr.Zero, 1, dataSize, new string[] { text }, rawData);

            //Remove temporary registration
            DeregisterEventSource(hEventLog);
        }
    }
